package servlet;

import it.polimi.swimv2.entities.FriendshipRequest;
import it.polimi.swimv2.exception.FriendshipRequestException;
import it.polimi.swimv2.remote.FriendshipRequestManagerRemote;
import it.polimi.swimv2.util.RemoteBindingName;

import java.io.IOException;
import java.util.Collection;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * Servlet implementation class FriendshipRequestServlet
 */
public class FriendshipRequestServlet extends HttpServlet {
	
	
	
	//Jsp pages	
	private static final String FRIENDSHIP_REQUESTS_LIST_JSP = "friendshipRequestsList.jsp";	
	private static final String ERROR_JSP = "error.jsp";
	private static final String INDEX_JSP = "index.jsp";
	private static final String LOGIN_FORM_JSP = "loginForm.jsp";
	//Parameters for HTTP Request
	private static final String ACT = "act";
	private static final String RQ_ID = "rqID";
	private static final String URL_SHOW_USER_PROFILE = "UserProfileServlet?act=showUserProfile&username=";
	private static final String USER = "user";
	private static final String RECEIVER = "receiver";
	private static final String SENT_REQUESTS = "sentRequests";
	private static final String RECEIVED_REQUESTS = "receivedRequests";
	private static final String SHOW_REQUESTS = "showRequests";
	private static final String CANCEL_REQUEST = "cancelRequest";
	private static final String REFUSE_REQUEST = "refuseRequest";
	private static final String ACCEPT_REQUEST = "acceptRequest";
	private static final String SEND_REQUEST = "sendRequest";
	
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public FriendshipRequestServlet() {
        super();
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		manageHttpRequest(request, response);
	}
	
	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		manageHttpRequest(request, response);
	}

	/**
	 * manages the action requested by http request
	 * @param request
	 * @param response
	 * @throws IOException
	 * @throws ServletException
	 */
	private void manageHttpRequest(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
		String act = request.getParameter(ACT);
		HttpSession session = request.getSession();
		String username = (String) session.getAttribute(USER);
		if(username==null){
			response.sendRedirect(LOGIN_FORM_JSP);
			return;
		}
		if(act!=null){
			if(act.equals(SEND_REQUEST)){
				processSendRequest(request, response);
			}else if(act.equals(ACCEPT_REQUEST)){
				processAcceptRequest(request, response);
			}else if(act.equals(REFUSE_REQUEST)){
				processRefuseRequest(request, response);
			}else if(act.equals(CANCEL_REQUEST)){
				processCancelRequest(request, response);
			}else if(act.equals(SHOW_REQUESTS)){
				processShowRequest(request, response);
			}else{
				response.sendRedirect(INDEX_JSP);
			}
		}else{
			response.sendRedirect(ERROR_JSP);
		}
	}
	/**
	 * 
	 * @param request
	 * @param response
	 * @throws IOException
	 * @throws ServletException
	 */
	private void processCancelRequest(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
		try{
			FriendshipRequestManagerRemote rem = (FriendshipRequestManagerRemote) retrieveFriendshipManagerRemote();
			String u = getHttpSession(request);
			Integer rqID = Integer.parseInt(request.getParameter(RQ_ID));
			rem.deleteFriendship(u,rqID);
			processPageUpdate(request, response, rem, u);
		}catch(NamingException e){
			response.sendRedirect(ERROR_JSP);
		} catch (FriendshipRequestException e) {
			response.sendRedirect(ERROR_JSP);
		}catch (NumberFormatException e){
			response.sendRedirect(ERROR_JSP);
		}
		
	}
	/**
	 * 
	 * @param request
	 * @param response
	 * @throws IOException
	 * @throws ServletException
	 */
	private void processRefuseRequest(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
		try{
			FriendshipRequestManagerRemote rem = (FriendshipRequestManagerRemote) retrieveFriendshipManagerRemote();
			String u = getHttpSession(request);
			Integer rqID = Integer.parseInt(request.getParameter(RQ_ID));
			rem.refuseFriendship(u,rqID);
			processPageUpdate(request, response, rem, u);
		}catch(NamingException e){
			response.sendRedirect(ERROR_JSP);
		} catch (FriendshipRequestException e) {
			response.sendRedirect(ERROR_JSP);
		}catch (NumberFormatException e){
			response.sendRedirect(ERROR_JSP);
		}
		
	}
	/**
	 * 
	 * @param request
	 * @param response
	 * @throws IOException
	 * @throws ServletException
	 */
	private void processAcceptRequest(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
		try{
			FriendshipRequestManagerRemote rem = (FriendshipRequestManagerRemote) retrieveFriendshipManagerRemote();
			String u = getHttpSession(request);
			Integer rqID = Integer.parseInt(request.getParameter(RQ_ID));
			rem.acceptFriendship(u,rqID);
			processPageUpdate(request, response, rem, u);
		}catch(NamingException e){
			response.sendRedirect(ERROR_JSP);
		} catch (FriendshipRequestException e) {
			response.sendRedirect(ERROR_JSP);
		}catch (NumberFormatException e){
			response.sendRedirect(ERROR_JSP);
		}
		
	}
	/**
	 * processes the action to show friendship requests
	 * @param request
	 * @param response
	 * @throws IOException
	 * @throws ServletException
	 */
	private void processShowRequest(HttpServletRequest request,	HttpServletResponse response) throws IOException, ServletException {
		try{
			FriendshipRequestManagerRemote rem = (FriendshipRequestManagerRemote) retrieveFriendshipManagerRemote();
			String u = getHttpSession(request);
			processPageUpdate(request, response, rem, u);
		}catch(NamingException e){
			response.sendRedirect(ERROR_JSP);
		} catch (FriendshipRequestException e) {
			response.sendRedirect(ERROR_JSP);
		}
	}
	/**
	 * shows the friendship requests list
	 * @param request
	 * @param response
	 * @param rem
	 * @param u
	 * @throws FriendshipRequestException
	 * @throws ServletException
	 * @throws IOException
	 */
	private void processPageUpdate(HttpServletRequest request, HttpServletResponse response, FriendshipRequestManagerRemote rem,
			String u) throws FriendshipRequestException, ServletException,
			IOException {
		Collection<FriendshipRequest> receivedRequests = rem.receivedFriendshipRequest(u);
		Collection<FriendshipRequest> sentRequests = rem.sentFriendshipRequest(u);	
		request.setAttribute(RECEIVED_REQUESTS, receivedRequests);
		request.setAttribute(SENT_REQUESTS, sentRequests);
		RequestDispatcher dispatcher = request.getRequestDispatcher(FRIENDSHIP_REQUESTS_LIST_JSP);
		dispatcher.forward(request, response);
	}
	/**
	 * 
	 * @param request
	 * @param response
	 * @throws IOException
	 * @throws ServletException
	 */
	private void processSendRequest(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
		
		try{
			FriendshipRequestManagerRemote rem = (FriendshipRequestManagerRemote) retrieveFriendshipManagerRemote();
			String sender = getHttpSession(request);
			String receiver = request.getParameter(RECEIVER);
			rem.sendFriendshipRequest(sender, receiver);
			redirectShowProfile(request, response, receiver);			
		}catch(NamingException e){
			response.sendRedirect(ERROR_JSP);
		} catch (FriendshipRequestException e) {
			response.sendRedirect(ERROR_JSP);
		}
		
	}
	/**
	 * 
	 * @param request
	 * @return
	 */
	private String getHttpSession(HttpServletRequest request) {
		HttpSession session = request.getSession();
		return (String) session.getAttribute(USER);
		
	}
	/**
	 * redirect the action to UserProfile servlet
	 * @param request
	 * @param response
	 * @param receiver
	 * @throws ServletException
	 * @throws IOException
	 */
	private void redirectShowProfile(HttpServletRequest request, HttpServletResponse response, String receiver) throws ServletException, IOException {
		String url = URL_SHOW_USER_PROFILE+receiver;
		RequestDispatcher dispatcher = request.getRequestDispatcher(url);
		dispatcher.forward(request, response);
		
	}
	/**
	 * retrieves the remote object
	 * @return
	 * @throws NamingException
	 */
	private FriendshipRequestManagerRemote retrieveFriendshipManagerRemote() throws NamingException {
		Context jndiContext = new InitialContext();
		Object ref = jndiContext.lookup(RemoteBindingName.FRIENDSHIP_REQUEST_MANAGER);
		return (FriendshipRequestManagerRemote) ref;
	}

	
}
